package cn.gjxblog.service.impl;

import cn.gjxblog.api.MailServiceFegin;
import cn.gjxblog.dao.UserMapper;
import cn.gjxblog.model.entity.User;
import cn.gjxblog.model.entity.UserExample;
import cn.gjxblog.service.UserService;
import cn.gjxblog.common.utils.HashUtils;
import cn.gjxblog.common.utils.JwtHelper;
import cn.gjxblog.common.utils.UUIDUtils;
import com.google.common.collect.ImmutableMap;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.Instant;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @author gjx
 * @version v1.0
 * @Description
 * @date 2018/12/7 16:28
 */
@Service
public class UserServiceImpl implements UserService {

    @Resource
    private UserMapper userMapper;

    @Autowired
    private MailServiceFegin mailServiceFeign;

    @Autowired
    private StringRedisTemplate redisTemplate;


    @Override
    public boolean addUser(User user, String enableUrl) {
        user.setId(UUIDUtils.get32LUUid());
        user.setPasswd(HashUtils.encryPassword(user.getPasswd()));
        user.setEnable(1);
        user.setCreateTime(new Date());

        userMapper.insertSelective(user);

//        registerNotify(user.getEmail(),enableUrl);
        return true;
    }


    /**
     * 发送注册激活邮件
     * @param email
     * @param enableUrl
     */
    private void registerNotify(String email, String enableUrl) {
        String randomKey = HashUtils.hashString(email) + RandomStringUtils.randomAlphabetic(10);
        redisTemplate.opsForValue().set(randomKey, email);
        redisTemplate.expire(randomKey, 1,TimeUnit.HOURS);
        String content = enableUrl +"?key="+  randomKey;
        mailServiceFeign.snedSimplMail("房产平台激活邮件", content, email);
    }

    @Override
    public void enable(String key) {
        String email = redisTemplate.opsForValue().get(key);
        if (StringUtils.isBlank(email)) {
            throw new RuntimeException("无效的key");
        }
        User user = new User();
        user.setEnable(1);
        UserExample userExample = new UserExample();
        userExample.createCriteria().andEmailEqualTo(email);
        userMapper.updateByExampleSelective(user,userExample);

    }



    /**
     * 校验用户密码，生成token并返回token
     * @param phone
     * @param passwd
     * @return
     */
    @Override
    public String auth(String phone, String passwd) {
        String loginPasswd = HashUtils.encryPassword(passwd);
        UserExample userExample = new UserExample();
        userExample.createCriteria().andPhoneEqualTo(phone).andPasswdEqualTo(loginPasswd).andEnableEqualTo(1);

        List<User> list = userMapper.selectByExample(userExample);
        if(!list.isEmpty()){
            User user = list.get(0);
//            onLogin(user);
            return  generatorToken(user);
        }
        return null;
    }

    private String generatorToken(User user) {
        String token =  JwtHelper.genToken(ImmutableMap.of("phone", user.getPhone(), "name", user.getName(),"ts",Instant.now().getEpochSecond()+""));
        return token;
    }

    @Override
    public User getLoginedUserByToken(String token) {
        Map<String, String> map = null;
        try {
            map = JwtHelper.verifyToken(token);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("User not login");
        }
        String phone =  map.get("phone");
//        Long expired = redisTemplate.getExpire(email);
        UserExample userExample = new UserExample();
        userExample.createCriteria().andPhoneEqualTo(phone);

        List<User> users = userMapper.selectByExample(userExample);
        User user = users.get(0);
        user.setToken(token);
        return  user;

//        if (expired > 0L) {
//            renewToken(token, email);
//
//            user.setToken(token);
//            return user;
//        }
//        throw new UserException(Type.USER_NOT_LOGIN,"user not login");
    }

    @Override
    public void invalidate(String token) {
        Map<String, String> map = JwtHelper.verifyToken(token);
        redisTemplate.delete(map.get("email"));
    }

    @Override
    public User updateUser(User user) {
        userMapper.updateByPrimaryKeySelective(user);
        User user1 = userMapper.selectByPrimaryKey(user.getId());
        return user1;
    }


    private void onLogin(User user) {
        String token =  JwtHelper.genToken(ImmutableMap.of("email", user.getEmail(), "name", user.getName(),"ts",Instant.now().getEpochSecond()+""));
        user.setToken(token);
    }

    @Override
    public User getUserById(String id) {
        User user = userMapper.selectByPrimaryKey(id);
        return user;
    }

    @Override
    public List<User> getUsersByCondition(User user) {
        List<User> users = userMapper.selectByExample(new UserExample());
        return users;
    }

    @Override
    public User getUserByEmail(String email) {
        UserExample userExample = new UserExample();
        userExample.createCriteria().andEmailEqualTo(email);

        List<User> users = userMapper.selectByExample(userExample);
        if(!users.isEmpty()){
            return  users.get(0);
        }
        return null;
    }

    @Override
    public void resetNotify(String email, String url) {
        String randomKey = "reset_" + RandomStringUtils.randomAlphabetic(10);
        redisTemplate.opsForValue().set(randomKey, email);
        redisTemplate.expire(randomKey, 1,TimeUnit.HOURS);
        String content = url +"?key="+  randomKey;
        mailServiceFeign.snedSimplMail("房产平台重置密码邮件", content, email);
    }

    @Override
    public String getEmailByKey(String key) {
        String email = redisTemplate.opsForValue().get(key);
        return email;
    }

    @Override
    public User resetPwd(String key, String password) {
        User user = new User();
        user.setId(key);
        user.setPasswd(HashUtils.encryPassword(password));


        userMapper.updateByPrimaryKeySelective(user);


        return user;
    }
}
